package xiaojian.toolkit.netty.transport.endpoint;

import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.ObjectName;

import org.apache.commons.collections4.Closure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jmx.export.MBeanExporter;

import io.netty.channel.ChannelHandlerContext;
import xiaojian.toolkit.netty.transport.Receiver;
import xiaojian.toolkit.netty.transport.TransportUtils;

public abstract class AbstractEndpoint<I> implements MutableEndpoint<I> {

	private static final Logger logger = LoggerFactory.getLogger(AbstractEndpoint.class);

	protected Closure<I> messageClosure;
	protected Receiver<I> nextReceiver;

	protected MBeanExporter mbeanExport = null;

	protected String objectNamePrefix;

	protected ObjectName objectName = null;

	/**
	 * @return the objectNamePrefix
	 */
	public String getObjectNamePrefix() {
		return objectNamePrefix;
	}

	/**
	 * @param objectNamePrefix
	 *            the objectNamePrefix to set
	 */
	public void setObjectNamePrefix(String objectNamePrefix) {
		this.objectNamePrefix = objectNamePrefix;
	}

	/**
	 * @return the mbeanExport
	 */
	public MBeanExporter getMbeanExport() {
		return mbeanExport;
	}

	/**
	 * @param mbeanExport
	 *            the mbeanExport to set
	 */
	public void setMbeanExport(MBeanExporter mbeanExport) {
		this.mbeanExport = mbeanExport;
	}

	public void messageReceived(ChannelHandlerContext ctx, I msg) {
		TransportUtils.attachSender(msg, this);
		
		if (null != messageClosure) {
			this.messageClosure.execute(msg);
		}
		if (null != nextReceiver) {
			this.nextReceiver.messageReceived(ctx, msg);
		}
	
	}
	
	/**
	 * 
	 * @see com.skymobi.transport.Endpoint#stop()
	 */
	public void stop() {
		if (null != objectName && null != mbeanExport) {
			try {
				mbeanExport.getServer().unregisterMBean(objectName);
			} catch (MBeanRegistrationException e) {
				logger.error("stop():", e);
			} catch (InstanceNotFoundException e) {
				logger.error("stop():", e);
			}
		}
	}

	public void setMessageClosure(Closure<I> closure) {
		this.messageClosure = closure;
	}

}
